using DG.Tweening;
using Framework.EventArg;
using Framework.MyAtrribute;
using Framework.ObjectPool;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
/// <summary>
/// 中小型UI界面
/// </summary>
public class SingleViewBase : MonoBehaviour
{

    public bool ifBlockTimeFlow;
    public string ObjectType;
    private Dictionary<Button, UnityAction> btnListenerDic = new Dictionary<Button, UnityAction>();
    private Dictionary<int, List<Action<EventArg>>> DATA_UIEvtDic = new Dictionary<int, List<Action<EventArg>>>();//数据-UI层事件
    private Dictionary<int, List<Action<EventArg>>> UI_UIEvtDic = new Dictionary<int, List<Action<EventArg>>>();//UI-UI事件

    public bool cannotRepeat = true;//能否重复（默认能重复）
    public bool isTemp = false;//是否是临时对象（默认否）


    /// <summary>
    /// 页面被创建时触发该方法
    /// </summary>
    public void UIInit()
    {
        _initDataListener();
        _initUIListener();
    }

    /// <summary>
    /// 初始化数据-UI事件监听
    /// </summary>
    private void _initDataListener()
    {
        DATA_UIEvtDic.Clear();
        var bindingFlag = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public;
        var mMethods = this.GetType().GetMethods(bindingFlag);
        foreach (var mMethodInfo in mMethods)
        {
            var mAttrObjs = mMethodInfo.GetCustomAttributes(typeof(DataListenerAttribute), false);
            if (mAttrObjs.Length > 0)
            {
                var mAttrObj = mAttrObjs[0] as DataListenerAttribute;
                var methodParameters = mMethodInfo.GetParameters();
                if (methodParameters.Length == 1 & methodParameters[0].ParameterType == typeof(EventArg))
                {
                    Action<EventArg> action = (EventArg rArg) => { mMethodInfo.Invoke(this, new object[] { rArg }); };
                    //viewManager.EventManager.BindEvent(mAttrObj.EventCode, action);
                    AddEventToDataListener(mAttrObj.evtCode, action);
                }
                else
                {
                    Debug.LogError("[DataListenerAttribute] 指定方法不符合规定，方法必须声明传参（EventArg） : " + mMethodInfo.Name, this);
                }
            }
        }
    }

    /// <summary>
    /// 绑定事件
    /// </summary>
    /// <param name="code"></param>
    /// <param name="action"></param>
    private void AddEventToDataListener(int code, Action<EventArg> action)
    {
        if (!this.DATA_UIEvtDic.ContainsKey(code))
            this.DATA_UIEvtDic[code] = new List<Action<EventArg>>();
        this.DATA_UIEvtDic[code].Add(action);
    }

    /// <summary>
    /// 初始化UI-UI事件监听
    /// </summary>
    private void _initUIListener()
    {
        UI_UIEvtDic.Clear();
        var bindingFlag = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public;
        var mMethods = this.GetType().GetMethods(bindingFlag);
        foreach (var mMethodInfo in mMethods)
        {
            var mAttrObjs = mMethodInfo.GetCustomAttributes(typeof(UIListenerAttribute), false);
            if (mAttrObjs.Length > 0)
            {
                var mAttrObj = mAttrObjs[0] as UIListenerAttribute;
                var methodParameters = mMethodInfo.GetParameters();
                if (methodParameters.Length == 1 & methodParameters[0].ParameterType == typeof(EventArg))
                {
                    Action<EventArg> action = (EventArg rArg) => { mMethodInfo.Invoke(this, new object[] { rArg }); };
                    //viewManager.EventManager.BindEvent(mAttrObj.EventCode, action);
                    AddEventToUIListener(mAttrObj.evtCode, action);
                }
                else
                {
                    Debug.LogError("[DataListenerAttribute] 指定方法不符合规定，方法必须声明传参（EventArg） : " + mMethodInfo.Name, this);
                }
            }
        }
    }

    /// <summary>
    /// 绑定事件
    /// </summary>
    /// <param name="code"></param>
    /// <param name="action"></param>
    private void AddEventToUIListener(int code, Action<EventArg> action)
    {
        if (!this.UI_UIEvtDic.ContainsKey(code))
            this.UI_UIEvtDic[code] = new List<Action<EventArg>>();
        this.UI_UIEvtDic[code].Add(action);
    }

    /// <summary>
    /// 数据赋值
    /// </summary>
    /// <param name="args"></param>
    public virtual void DataInit(object[] args)
    {
        //该面板在初始化时的数据赋值
    }
    /// <summary>
    /// 面板打开时
    /// </summary>
    public virtual void OnOpenIng()
    {
        if (ifBlockTimeFlow)
        {
            Debug.Log(name + "调用时停");
            PanelManager.Instance.AddblockTimeFlowPage();
        }

        foreach (var item in DATA_UIEvtDic)
        {
            foreach (var action in item.Value)
            {
                EventCenter.AddDataListener(item.Key, action);
            }
        }

        foreach (var item in UI_UIEvtDic)
        {
            foreach (var action in item.Value)
            {
                EventCenter.AddUIListener(item.Key, action);
            }
        }

    }
    /// <summary>
    /// 面板关闭时
    /// </summary>
    public virtual void OnCloseIng()
    {
        if (ifBlockTimeFlow)
        {
            Debug.Log(name + "取消时停");
            PanelManager.Instance.RemoveblockTimeFlowPage();
        }

        foreach (var item in DATA_UIEvtDic)
        {
            foreach (var action in item.Value)
            {
                EventCenter.RemoveDataListener(item.Key, action);
            }
        }
        foreach (var item in UI_UIEvtDic)
        {
            foreach (var action in item.Value)
            {
                EventCenter.RemoveUIListener(item.Key, action);
            }
        }
    }
    /// <summary>
    /// 清理
    /// </summary>
    public virtual void Clear()
    {

    }


    /// <summary>
    /// 关闭
    /// </summary>
    public void Closed()
    {
        PanelManager.Instance.OnSingleClosed(new object[] { this });
        OnCloseIng();
        RemoveBtnClick();
        HideObj(isTemp);
        Clear();
    }

    /// <summary>
    /// 关闭物体 进对象池(默认进永久）
    /// </summary>
    void HideObj(bool isTemp)
    {
        string name = this.gameObject.name;
        //Debug.Log(name);
        /*PoolType singleType = ObjectType;
        if (singleType == PoolType.None)
            singleType = (PoolType)Enum.Parse(typeof(PoolType), name);*/
        ObjectPoolManager.Instance.SaveObject(name, gameObject, isTemp);
    }


    #region 事件
    /// <summary>
    /// 增加按钮点击事件
    /// </summary>
    /// <param name="btn"></param>
    /// <param name="listener"></param>
    public virtual void AddBtnListener(Button btn, UnityEngine.Events.UnityAction listener)
    {
        if (!btnListenerDic.ContainsKey(btn))
        {
            btn.onClick.AddListener(listener);
            btnListenerDic.Add(btn, listener);
        }
    }
    /// <summary>
    /// 移除按钮点击事件
    /// </summary>
    void RemoveBtnClick()
    {
        if (btnListenerDic != null && btnListenerDic.Count > 0)
        {
            foreach (KeyValuePair<Button, UnityEngine.Events.UnityAction> kv in btnListenerDic)
            {
                Button btn = kv.Key;
                UnityEngine.Events.UnityAction action = kv.Value;
                if (btn != null)
                    btn.onClick.RemoveAllListeners();
            }
            btnListenerDic.Clear();

        }
    }



    #endregion



}

